/*
 * AccountTests.java
 *
 *  
 */
package org.msb.finance.data;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.math.BigDecimal;
import java.util.Currency;
import java.util.Date;
import java.util.Locale;

import org.junit.Before;
import org.junit.Test;

/**
 * 
 * 
 * @author Marc Boudreau
 * 
 */
@SuppressWarnings("nls")
public class AccountTests {

	/*
	 * 
	 */
	private Account account;

	/**
	 * @throws Exception
	 */
	@Before
	public void setUp() throws Exception {
		account = new FakeAccount("Test Account");
	}

	/**
	 * Test method for {@link Account#setName(String)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetName() throws Exception {
		final String NAME = "Test Account";
		account.setName(NAME);

		assertEquals(NAME, account.getName());

		final String NAME2 = "Test Account 2";
		account.setName(NAME2);

		assertEquals(NAME2, account.getName());
	}

	/**
	 * Test method for {@link Account#setAccountNumber(String)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetAccountNumber() throws Exception {
		final String ACCOUNTNUM = "00-12345678";
		account.setAccountNumber(ACCOUNTNUM);

		assertEquals(ACCOUNTNUM, account.getAccountNumber());

		final String ACCOUNTNUM2 = "00-12345679";
		account.setAccountNumber(ACCOUNTNUM2);

		assertEquals(ACCOUNTNUM2, account.getAccountNumber());
	}

	/**
	 * Test method for {@link Account#setLastUpdate(Date)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetLastUpdate() throws Exception {
		final Date LASTUPDATE = new Date(3429874243124L);
		account.setLastUpdate(LASTUPDATE);

		assertEquals(LASTUPDATE, account.getLastUpdate());

		final Date LASTUPDATE2 = new Date(2429876243124L);
		account.setLastUpdate(LASTUPDATE2);

		assertEquals(LASTUPDATE2, account.getLastUpdate());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetLastUpdateToNull() throws Exception {
		account.setLastUpdate(null);

		assertNull(account.getLastUpdate());
	}

	/**
	 * Test method for {@link Account#setUnreviewedTransactions(int)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetUnreviewedTransactions() throws Exception {
		final int COUNT = 5;
		account.setUnreviewedTransactions(COUNT);

		assertEquals(COUNT, account.getUnreviewedTransactions());

		final int COUNT2 = 0;
		account.setUnreviewedTransactions(COUNT2);

		assertEquals(COUNT2, account.getUnreviewedTransactions());
	}

	/**
	 * Test method for {@link Account#setReportedBalance(BigDecimal)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetReportedBalance() throws Exception {
		final BigDecimal BALANCE = new BigDecimal(1000.5f);
		account.setReportedBalance(BALANCE);

		assertEquals(BALANCE, account.getReportedBalance());

		final BigDecimal BALANCE2 = new BigDecimal(-2300.79f);
		account.setReportedBalance(BALANCE2);

		assertEquals(BALANCE2, account.getReportedBalance());

		final BigDecimal BALANCE3 = new BigDecimal(0);
		account.setReportedBalance(BALANCE3);

		assertEquals(BALANCE3, account.getReportedBalance());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetReportedBalanceToNull() throws Exception {
		account.setReportedBalance(null);

		assertNull(account.getReportedBalance());
	}

	/**
	 * Test method for {@link Account#setInstitution(Institution)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetInstitution() throws Exception {
		final Institution INSTITUTION = new Institution();
		INSTITUTION.setName("Test Institution");
		account.setInstitution(INSTITUTION);

		assertEquals(INSTITUTION, account.getInstitution());

		final Institution INSTITUTION2 = new Institution();
		INSTITUTION2.setName("Test Institution 2");
		account.setInstitution(INSTITUTION2);

		assertEquals(INSTITUTION2, account.getInstitution());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetInstitutionToNull() throws Exception {
		account.setInstitution(null);

		assertNull(account.getInstitution());
	}

	/**
	 * Test method for {@link Account#setDescription(String)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetDescription() throws Exception {
		final String DESCRIPTION = "A test description.";
		account.setDescription(DESCRIPTION);

		assertEquals(DESCRIPTION, account.getDescription());

		final String DESCRIPTION2 = "A different test description.";
		account.setDescription(DESCRIPTION2);

		assertEquals(DESCRIPTION2, account.getDescription());
	}

	/**
	 * Test method for {@link Account#setClosed(boolean)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetClosed() throws Exception {
		account.setClosed(true);
		assertTrue(account.isClosed());

		account.setClosed(false);
		assertFalse(account.isClosed());
	}

	/**
	 * Test method for {@link Account#setCurrency(Currency)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetCurrency() throws Exception {
		final Currency CAD = Currency.getInstance(Locale.CANADA);
		account.setCurrency(CAD);

		assertEquals(CAD, account.getCurrency());

		final Currency USD = Currency.getInstance(Locale.US);
		account.setCurrency(USD);

		assertEquals(USD, account.getCurrency());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetStartingBalance() throws Exception {
		final BigDecimal BALANCE = new BigDecimal(1230.46f);
		account.setStartBalance(BALANCE);

		assertEquals(BALANCE, account.getStartBalance());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetStartingBalanceNegative() throws Exception {
		final BigDecimal BALANCE = new BigDecimal(-4230.46f);
		account.setStartBalance(BALANCE);

		assertEquals(BALANCE, account.getStartBalance());
	}

	/**
	 * Test method for {@link BankAccount#getBalance()}.
	 */
	@Test
	public void testGetBalance() {
		assertEquals(new BigDecimal(0), account.getBalance());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testGetNonZeroBalance() throws Exception {
		final BigDecimal BALANCE = new BigDecimal(55.46f);
		final Transaction TRANSACTION = new Transaction();
		final CashTransactionDetail CTD = new CashTransactionDetail();

		CTD.setAmount(BALANCE);
		TRANSACTION.addTransactionDetail(CTD);
		account.addTransaction(TRANSACTION);

		assertEquals(BALANCE, account.getBalance());
	}

	/**
	 * Test method for {@link Account#compareTo(Account)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testCompareTo() throws Exception {
		final Account ACCOUNT1 = new FakeAccount("AAA-" + account.getName());
		final Account ACCOUNT2 = new FakeAccount("ZZZ-" + account.getName());

		assertEquals(0, account.compareTo(account));

		assertTrue(0 < account.compareTo(ACCOUNT1));
		assertTrue(0 > ACCOUNT1.compareTo(account));

		assertTrue(0 > account.compareTo(ACCOUNT2));
		assertTrue(0 < ACCOUNT2.compareTo(account));
	}

	/*
	 * 
	 */
	private class FakeAccount extends Account {

		/*
		 * 
		 */
		FakeAccount(String name) {
			super(name);
		}

	}
}
